package com.java.basis.thread.cas.atomic;

import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.builder.ToStringBuilder;

import java.util.concurrent.atomic.AtomicMarkableReference;

/**
 * AtomicMarkableReference : 可以记录是否被改过
 *
 * @author wangning
 * @create 2022-01-28 16:07
 */
@Slf4j(topic = "c.TestABA04")
public class TestABA04 {

	public static void main(String[] args) throws InterruptedException {
		GarbageBag bag = new GarbageBag("装满了垃圾");
		//参数2可以看做一个标记，表示垃圾袋是否已满
		AtomicMarkableReference<GarbageBag> ref = new AtomicMarkableReference<>(bag, true);
		log.debug("start ...");
		GarbageBag prev = ref.getReference();
		log.debug(prev.toString());

		new Thread(() -> {
			log.debug("start...");
			bag.setDesc("空垃圾袋");
			ref.compareAndSet(bag, bag, true, false);
			log.debug(bag.toString());

		}, "保洁").start();

		Thread.sleep(1000);

		log.debug("想换一只新的垃圾袋");
		boolean success = ref.compareAndSet(prev, new GarbageBag("空垃圾袋"), true, false);
		log.debug("换了吗？" + success);
		log.debug(ref.getReference().toString());

	}

}

class GarbageBag {
	private String desc;

	public GarbageBag(String desc) {
		this.desc = desc;
	}

	public String getDesc() {
		return desc;
	}

	public void setDesc(String desc) {
		this.desc = desc;
	}

	@Override
	public String toString() {
		return new ToStringBuilder(this)
				.append("desc", desc)
				.toString();
	}
}
